#pragma	once

#include "ZGameMessage.h"
#include "ZStream.h"
#include <boost/function.hpp>

namespace	Z	{

//------------------------------------------------------------------------------------------------------------------------
class	Stream;

//------------------------------------------------------------------------------------------------------------------------
struct	GameMessageCommand
{
	virtual	~GameMessageCommand()	{}
	virtual	void	execute(Stream& stream, NetworkId kNetworkId)	= 0;
	virtual	GameMessageId	getGameMessageId()	const	= 0;
};

//------------------------------------------------------------------------------------------------------------------------
template<typename GameMessageT>
class	GameMessageCommandT
	:	public GameMessageCommand
{
private:
	typedef	boost::function1<void, GameMessageT&>	Functor;

public:
	GameMessageCommandT(Functor functor)	:	mFunctor(functor)	{}
private:
	virtual	void	execute(Stream& stream, NetworkId kNetworkId)	{
		GameMessageT message(kNetworkId);
		message.deserialize(stream);
		mFunctor(message);
	}
	virtual	GameMessageId	getGameMessageId()	const	{	return GameMessageT::id;		}
	
private:
	Functor	mFunctor;
};

}